package com.example.stlink.utils;

import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Build;
import android.text.TextUtils;
import android.view.View;

import androidx.appcompat.app.AppCompatActivity;

import com.example.stlink.R;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;

/**
 * 一些公共方法
 */
public class CommonUtils {

    /**
     * 加密/解密密钥
     */
    private final static char secret = 'Z';

    /**
     * 简单的异或运算进行加密和解密
     * @param value 值
     * @return 加密后数据
     */
    public static String encryptAndDencrypt(String value) {
        byte[] bt = value.getBytes(); // 将需要加密的内容转换为字节数组
        for (int i = 0; i < bt.length; i++) {
            bt[i] = (byte) (bt[i] ^ (int) secret); // 通过异或运算进行加密
        }
        return new String(bt, 0, bt.length);
    }

    /**
     * MD5加密方法
     * @param data 待加密数据
     * @return 加密后数据
     */
    public static String MD5(String data)  {
        try {
            java.security.MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] array = md.digest(data.getBytes(StandardCharsets.UTF_8));
            StringBuilder sb = new StringBuilder();
            for (byte item : array) {
                sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));
            }
            return sb.toString().toUpperCase();
        } catch (Exception exception) {
            exception.printStackTrace();
        }
        return null;
    }


    /**
     * 密码保存到本地
     * @param appCompatActivity 上下文
     * @param password 密码
     * @param account 账户
     * @param isChecked 是否保存
     */
    public static void localSave(AppCompatActivity appCompatActivity, String account, String password, Boolean isChecked){
        String spFileName = appCompatActivity.getResources()
                .getString(R.string.shared_preferences_file_name);
        String accountKey = appCompatActivity.getResources()
                .getString(R.string.login_account_name);
        String passwordKey = appCompatActivity.getResources()
                .getString(R.string.login_password);
        String rememberPasswordKey = appCompatActivity.getResources()
                .getString(R.string.login_remember_password);

        SharedPreferences spFile = appCompatActivity.getSharedPreferences(
                spFileName,
                Context.MODE_PRIVATE
        );
        SharedPreferences.Editor editor = spFile.edit();

        if(isChecked){
            editor.putString(accountKey, account);
            editor.putString(passwordKey, encryptAndDencrypt(password));
            editor.putBoolean(rememberPasswordKey, true);
            editor.apply();
        }else{
            editor.remove(accountKey);
            editor.remove(passwordKey);
            editor.remove(rememberPasswordKey);
            editor.apply();
        }
    }

    /**
     * 实现状态栏文字颜色为暗色
     * @param appCompatActivity 上下文
     */
    public static void changeStatusBar(AppCompatActivity appCompatActivity) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            appCompatActivity.getWindow()
                    .getDecorView()
                    .setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
        }
    }

    /**
     * 销毁任务栈
     * 直接调用系统 API获取当前的任务栈，把里面的Activity全部销毁掉。
     * 不过该方法简单粗暴，需要 API 21（Android 5.0）以上才可以使用。
     * @param context 上下文
     */
    public static void exitApp(Context context){
        ActivityManager activityManager = (ActivityManager) context.getApplicationContext()
                                                                .getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.AppTask> appTaskList = activityManager.getAppTasks();
        for (ActivityManager.AppTask appTask : appTaskList) {
            appTask.finishAndRemoveTask();
        }
    }


    /**
     * 先根据注册规则进行初次校验
     * @param id 账户
     * @param pwd 密码
     * @return 校验结果
     */
    public static Boolean localCheck(String id, String pwd){

        return isLegalId(id) && isLegalPwd(pwd);

    }

    /**
     * @param pwd 密码
     * @return 是否成功
     */
    public static Boolean pwdCheck(String pwd){
        // MD5后的密码传输到云端，与数据库中的密码进行校验
        CommonUtils.MD5(pwd);
        return true;
    }


    /**
     * 以下情形id不合法
     * 1、为空
     * 2、字符串长度小于6，或者大于32
     * 3、第一个字符为非字母字符
     * 4、id中包含非数字，字母，还有下划线存在
     * 3、包括一种隐形标准，数据库中已经存在该用户
     * @param id id
     * @return 是否合法
     */
    public static boolean isLegalId(String id){

        int len = id.length();
        if(TextUtils.isEmpty(id) || len < 6 || len > 32){
            return false;
        } else {
            char firstCh = id.charAt(0);
            if( (firstCh >= 'a' && firstCh <= 'z') || (firstCh >= 'A' && firstCh <= 'Z')){
                for(int i = 1; i < len; i++){
                    char nowCh = id.charAt(i);
                    if( !(nowCh == '_' ||
                            (nowCh >= 'a' && nowCh <= 'z') ||
                            (nowCh >= 'A' && nowCh <= 'Z') ||
                            (nowCh >= '0' && nowCh <= '9')) ){
                        return false;
                    }
                }
                return true;
            }else{
                return false;
            }
        }
    }

    /**
     * 以下情形密码不合法
     * 1、密码长度为空
     * 2、包含空格
     * @param pwd 密码
     * @return 是否合法
     */
    public static boolean isLegalPwd(String pwd){

        int len = pwd.length();
        if(len == 0){
            return false;
        }
        for (int i = 0; i < len; i++){
            if(pwd.charAt(i) == ' '){
                return false;
            }
        }
        return true;
    }

    /**
     * 检验两次输入密码是否相同
     * @param pwdFirst 第一次密码
     * @param pwdSecond 第二次密码
     * @return 校验结果
     */
    public static boolean isSamePwd(String pwdFirst, String pwdSecond){

        int lenFirst = pwdFirst.length();
        int lenSecond = pwdSecond.length();
        if(lenFirst != lenSecond){
            return false;
        }
        for(int i = 0; i < lenFirst; i++){
            if(pwdFirst.charAt(i) != pwdSecond.charAt(i)){
                return false;
            }
        }
        return true;
    }


    /**
     * 将时间戳转换为时间
     * @param s 时间戳
     * @return 返回yyyy-MM-dd HH:mm:ss格式的字符串
     */
    public static String stampToDate(String s) {
        String res;
        @SuppressLint("SimpleDateFormat")
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        //需要加八个格林威治时间
        simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));
        //如果它本来就是long类型的,则不用写这一步
        long lt = Long.parseLong(s);
        Date date = new Date(lt);
        res = simpleDateFormat.format(date);
        return res;
    }

    /**
     * 将时间戳转换为时间
     * @param s 时间戳
     * @param fprmat 指定格式
     * @return 指定格式的字符串
     */
    public static String stampToDate(String s, String fprmat) {
        String res;
        @SuppressLint("SimpleDateFormat")
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(fprmat);
//        simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));
        //如果它本来就是long类型的,则不用写这一步
        long lt = Long.parseLong(s);
        Date date = new Date(lt);
        res = simpleDateFormat.format(date);
        return res;
    }

    /**
     * 将时间转换为时间戳
     * @param s 时间
     * @return 时间戳
     * @throws ParseException 解析异常
     */
    @SuppressLint("SimpleDateFormat")
    public static String dateToStamp(String s, String fprmat) throws ParseException {
        String res;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(fprmat);
        simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));
        Date date = simpleDateFormat.parse(s);
        assert date != null;
        long ts = date.getTime();
        res = String.valueOf(ts);
        return res;
    }

    /**
     * 将时间转换为时间戳
     * @param s 时间
     * @return 时间戳
     * @throws ParseException 解析异常
     */
    @SuppressLint("SimpleDateFormat")
    public static String dateToStamp(String s) throws ParseException {
        String res;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        simpleDateFormat.setTimeZone(TimeZone.getTimeZone("GMT+8:00"));
        Date date = simpleDateFormat.parse(s);
        assert date != null;
        long ts = date.getTime();
        res = String.valueOf(ts);
        return res;
    }
}
